package com.otitan.forest.right.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.otitan.forest.right.dto.SysOrganizationDto;
import com.otitan.forest.right.dto.TreeDto;
import com.otitan.forest.right.entity.SysOrganizationEntity;
import com.otitan.forest.right.entity.SysUserEntity;
import com.otitan.forest.right.mapper.SysOrganizationMapper;
import com.otitan.forest.right.service.SysOrganizationService;
import com.otitan.forest.right.service.SysUserService;
import com.otitan.webapp.framework.basepro.exception.BusinessException;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;


@Service("sysOrganizationService")
public class SysOrganizationServiceImpl extends ServiceImpl<SysOrganizationMapper, SysOrganizationEntity> implements SysOrganizationService {

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private SysOrganizationMapper sysOrganizationMapper;

    @Override
    public void checkInsertSysOrganization(SysOrganizationEntity sysOrganization) {
        if (sysOrganization == null) {
            throw new BusinessException("机构信息不能为空！");
        }
        LambdaQueryWrapper<SysOrganizationEntity> queryWrapper = Wrappers.lambdaQuery();
        //查询条件示例
        queryWrapper.eq(SysOrganizationEntity::getParentId, sysOrganization.getParentId());
        queryWrapper.eq(SysOrganizationEntity::getName, sysOrganization.getName());
        SysOrganizationEntity sysOrganizationEntity = getOne(queryWrapper);
        if (sysOrganizationEntity != null) {
            throw new BusinessException(sysOrganizationEntity.getName() + "机构已存在！");
        }
    }

    @Override
    public void checkDeleteSysOrganization(List<String> ids) {
        List<SysOrganizationEntity> sysOrganizationEntities = listByIds(ids);
        for (SysOrganizationEntity sysOrganizationEntity : sysOrganizationEntities) {
            Map<String, Object> map = new HashMap<>();
            map.put("PARENT_ID", sysOrganizationEntity.getId());
            List<SysOrganizationEntity> sysOrganizationEntityList = listByMap(map);
            if (sysOrganizationEntityList != null && sysOrganizationEntityList.size() > 0) {
                throw new BusinessException(sysOrganizationEntity.getName() + "下存在子机构！不可删除");
            }
            List<SysUserEntity> sysUserEntities = sysUserService.findByGroupId(sysOrganizationEntity.getId());
            if (sysUserEntities != null && sysUserEntities.size() > 0) {
                throw new BusinessException(sysOrganizationEntity.getName() + "下存在用户！不可删除");
            }
        }
    }

    @Override
    public void checkUpdateSysOrganization(SysOrganizationEntity sysOrganization) {
        if (sysOrganization == null) {
            throw new BusinessException("机构信息不能为空！");
        }
        if (!StringUtils.isEmpty(sysOrganization.getName())) {
            LambdaQueryWrapper<SysOrganizationEntity> queryWrapper = Wrappers.lambdaQuery();
            //查询条件示例
            queryWrapper.eq(SysOrganizationEntity::getParentId, sysOrganization.getParentId());
            queryWrapper.eq(SysOrganizationEntity::getName, sysOrganization.getName());
            SysOrganizationEntity sysOrganizationEntity = getOne(queryWrapper);
            if (sysOrganizationEntity != null && !sysOrganizationEntity.getId().equals(sysOrganization.getId())) {
                throw new BusinessException(sysOrganizationEntity.getName() + "机构已存在！");
            }
        }
    }

    @Override
    public List<TreeDto> getSysOrganizationTree() {
        return getOrgByLevels("1,2,3,4");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addOrUpdateSysOrganization(SysOrganizationDto sysOrganizationDto) {
        List<SysOrganizationEntity> sysOrganizations = sysOrganizationDto.getSysOrganization();
        for (SysOrganizationEntity sysOrganizationEntity : sysOrganizations) {
            sysOrganizationEntity.setParentId(sysOrganizationDto.getParentId());
            if (StringUtils.isEmpty(sysOrganizationEntity.getId())) {
                checkInsertSysOrganization(sysOrganizationEntity);
                save(sysOrganizationEntity);
            } else {
                checkUpdateSysOrganization(sysOrganizationEntity);
                updateById(sysOrganizationEntity);
            }
        }

    }

    @Override
    public List<TreeDto> getOrgByLevels(String levels) {
        LambdaQueryWrapper<SysOrganizationEntity> queryWrapper = Wrappers.lambdaQuery();

        String[] split = levels.split(",");
        //查询条件示例
        queryWrapper.in(SysOrganizationEntity::getLevel, split);
        List<SysOrganizationEntity> list = this.list(queryWrapper);
        String data = JSONArray.toJSONString(list);
        return JSONArray.parseArray(data, TreeDto.class);
    }

    @Override
    public List<TreeDto> getSysOrganizationById(String parentId, Boolean type, Integer level) {
        if (StrUtil.isBlank(parentId)) {
            parentId = "520000";
        }

        List<TreeDto> treeDtos = null;

        //查询条件示例
        LambdaQueryWrapper<SysOrganizationEntity> queryWrapper = Wrappers.lambdaQuery();
        if (type != null && type){
            String pId = "";
            switch (level) {
                case 1:
                    // 省 520000
                    pId = parentId.substring(0, 2);
                    break;
                case 2:
                    // 市 520100
                    pId = parentId.substring(0, 4);
                    break;
                case 3:
                    // 县 520101
                    pId = parentId.substring(0, 6);
                    break;
                case 4:
                    // 乡、镇、街道 520101001
                    pId = parentId.substring(0, 9);
                    break;
                default:
                    break;
            }
            queryWrapper.likeRight(SysOrganizationEntity::getParentId, pId);
        } else {
            queryWrapper.eq(SysOrganizationEntity::getParentId, parentId);
        }


        List<SysOrganizationEntity> list = this.list(queryWrapper);
        if (type != null && type){
            treeDtos = formatData(list, parentId);
        } else {
            String data = JSONArray.toJSONString(list);
            treeDtos = JSONArray.parseArray(data, TreeDto.class);

            treeDtos.forEach(item -> {
                if (item.getLevel() < 4) {
                    item.setHaveChildren(Boolean.TRUE);
                } else {
                    item.setHaveChildren(Boolean.FALSE);
                }
            });
        }

        return treeDtos;
    }
    /**
     * 格式化菜单数据
     * @author jiachangsen
     * @param [list]
     * @return java.util.List<com.otitan.pms.sysmanager.dto.MenuDto>
     * @exception
     * @date 2020/07/16 13:18
     */
    private List<TreeDto> formatData(List list,String parentId) {

        if (list != null){
            List<TreeDto> menuDtos = JSONObject.parseArray(JSONObject.toJSONString(list), TreeDto.class);

            List<TreeDto> res = new ArrayList<>();

            menuDtos.forEach(item -> {
                if (parentId.equals(item.getParentId())){
                    res.add(item);
                }
            });
            for (TreeDto re : res) {
                recursive(re, menuDtos);
            }
            return res;
        }
        return null;
    }
    /**
     * 递归创建菜单树
     * @author jiachangsen
     * @param [res, menuDtos]
     * @return void
     * @exception
     * @date 2020/07/16 13:24
     */
    private void recursive(TreeDto res, List<TreeDto> menuDtos) {
        for (TreeDto dto : menuDtos) {
            if (res.getId().equals(dto.getParentId())) {
                recursive(dto, menuDtos);
                res.getChildren().add(dto);
            }
        }
    }
    @Override
    public List<String> getGroupId(String orgId) {
        List<String> stringList = new ArrayList<>();
        List<String> groupList = null;
        stringList.add(orgId);
        String groupIds = getAllChildGroupId(stringList, orgId);
        groupList = Arrays.asList(groupIds.split(","));

        return groupList;
    }

    public String getAllChildGroupId(List<String> ids, String str) {
        if (ids.size() == 0) {
            return "";
        }
        List<String> groups = sysOrganizationMapper.findByParentId(ids);

        for (String id : groups) {
            if (id != null) {
                str = str + "," + id;
            }
        }
        return str + getAllChildGroupId(groups, "");
    }

}